package com.lujieni.threadpool.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.stream.Stream;

@Service
@Slf4j
public class PriceService {

    @Autowired
    private ThreadPoolTaskExecutor lujieniAsyncPool;

    /**
     * 使用线程池提交任务
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public BigDecimal getCheapPrice() throws ExecutionException, InterruptedException {
        Future<BigDecimal> taoBao = lujieniAsyncPool.submit(() -> {
            return calTaoBao();
        });

        Future<BigDecimal> jd = lujieniAsyncPool.submit(() -> {
            return calJd();
        });

        Future<BigDecimal> pdd = lujieniAsyncPool.submit(() -> {
            return calPdd();
        });

        BigDecimal bigDecimal = Stream.of(taoBao, jd, pdd).map(e -> {
            try {
                return e.get();
            } catch (InterruptedException ex) {
                throw new RuntimeException(ex);
            } catch (ExecutionException ex) {
                throw new RuntimeException(ex);
            }
        }).filter(Objects::nonNull).sorted((BigDecimal::compareTo)).findFirst().get();
        return bigDecimal;
    }


    public BigDecimal calTaoBao() throws InterruptedException {
        log.info("查询淘宝价格");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal originPrice = new BigDecimal("100");

        log.info("查询淘宝折扣");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal discount = new BigDecimal("0.6");

        log.info("计算淘宝最终价格");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal finalPrice = originPrice.multiply(discount);
        return finalPrice;
    }

    public BigDecimal calJd() throws InterruptedException {
        log.info("查询京东价格");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal originPrice = new BigDecimal("100");

        log.info("查询京东折扣");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal discount = new BigDecimal("0.8");

        log.info("计算京东最终价格");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal finalPrice = originPrice.multiply(discount);
        return finalPrice;
    }

    public BigDecimal calPdd() throws InterruptedException {
        log.info("查询pdd价格");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal originPrice = new BigDecimal("100");

        log.info("查询pdd折扣");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal discount = new BigDecimal("0.7");

        log.info("计算pdd最终价格");
        TimeUnit.SECONDS.sleep(2);
        BigDecimal finalPrice = originPrice.multiply(discount);
        return finalPrice;
    }


    public BigDecimal getCheapPriceWithCompletableFuture() {
        CompletableFuture<BigDecimal> taoBao = CompletableFuture.supplyAsync(() -> {
            log.info("查询淘宝价格");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            BigDecimal originPrice = new BigDecimal("100");
            return originPrice;
        }, lujieniAsyncPool).thenCombine(CompletableFuture.supplyAsync(() -> {
            log.info("查询淘宝折扣");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            BigDecimal discount = new BigDecimal("0.6");
            return discount;
        }, lujieniAsyncPool), (o1, o2) -> o1.multiply(o2));

        CompletableFuture<BigDecimal> jd = CompletableFuture.supplyAsync(() -> {
            log.info("查询京东价格");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            BigDecimal originPrice = new BigDecimal("100");
            return originPrice;
        }, lujieniAsyncPool).thenCombine(CompletableFuture.supplyAsync(() -> {
            log.info("查询京东折扣");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            BigDecimal discount = new BigDecimal("0.6");
            return discount;
        }, lujieniAsyncPool), (o1, o2) -> o1.multiply(o2));

        CompletableFuture<BigDecimal> pdd = CompletableFuture.supplyAsync(() -> {
            log.info("查询pdd价格");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            BigDecimal originPrice = new BigDecimal("100");
            return originPrice;
        }, lujieniAsyncPool).thenCombine(CompletableFuture.supplyAsync(() -> {
            log.info("查询pdd折扣");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            BigDecimal discount = new BigDecimal("0.6");
            return discount;
        }, lujieniAsyncPool), (o1, o2) -> o1.multiply(o2));


        BigDecimal bigDecimal = Stream.of(taoBao, jd, pdd).map(e -> {
            try {
                return e.get();
            } catch (InterruptedException ex) {
                throw new RuntimeException(ex);
            } catch (ExecutionException ex) {
                throw new RuntimeException(ex);
            }
        }).filter(Objects::nonNull).sorted((BigDecimal::compareTo)).findFirst().get();
        return bigDecimal;

    }

    public static BigDecimal computeRealPrice(BigDecimal orignPrice, BigDecimal discount){
        return orignPrice.multiply(discount);
    }
}
